<?php
/**
* 用户收益模块 工具类
*
* 用户收益模块 工具类
* 以下use模块请不要互相伤害
*
* @author    xiecz <xiecz@yunys.com.cn>
* @copyright 2016 QuanZhouYunYiShang Inc.
*/
namespace App\Services\Tool\Statistics;

use Log;
use Illuminate\Support\Facades\DB;
use App\Services\Tool\DataBase\SQL;
use App\Services\Tool\GeneralTool;
use App\Services\Tool\Jpush\JpushTool;
use App\Services\UserService\UserTool;

class IncomeTool{
    function __construct(UserTool $userTool){
        $this->userTool = $userTool;
    }
    /**
     * API
     * @param  [type] $input [description]
     * @return [type]        [description]
     */
    function getUserIncomes($input){

        $times = $this->getSelectTimeArray($input);
        $type  = isset($input['type'])?$input['type']:'product';
        $time  = [];
        $price = [];

        for($a=0;$a<count($times);$a++){
            $times[$a]['total_fee'] = $this->getUserIncomeByTime(['user_id'         => $input['user_id'],
                                                                  'resource_type'   => $type,
                                                                  'change_type'     => 1,
                                                                  'type'            => 'income',
                                                                  'state'           => 1
                                                                  ],
                                                                 [$times[$a]['begin_time'],
                                                                  $times[$a]['end_time']]);
            $time[] = $times[$a]['title'];
            $price[] = $times[$a]['total_fee'];
        }
        //dd($times);
        return ['time'=>$time,'price'=>$price];
    }

    //获取统计时间分段
    function getSelectTimeArray($input){

        $today             = strtotime(date('Y-m-d',time()).' 23:59:59');   //今天时间戳23时59分59秒时
        $input['duration'] = isset($input['duration'])?$input['duration']:'week'; //时长

        $time = [];

        switch($input['duration']){
            case 'week':

                $one    = 3600*24;
                $num    = 7;
                $oneday = $today - $one * $num;

                for($a = 0; $a<$num; $a++){
                    $oneday += $one;
                    if($oneday>$today) break;
                    $time[] = ['title'=>date('m-d',$oneday),'end_time'=>$oneday,'begin_time'=>($oneday-$one)];
                }
                break;
        }
        //dd($time);
        return $time;
    }

    //获取用户时间段内收益
    function getUserIncomeByTime($input,$time){
        //dd(SQL::lists(['table'=>'users','where'=>['state'=>1],'lists'=>'user_id'])[0]);
        $prices = DB::table('user_balance_changes')
                  ->where($input)
                  ->whereBetween('created_at',$time)
                  ->pluck('price')->toArray();

        return array_sum($prices);
    }

    //收益明细
    function incomeStatement($input,$per_page){
        $result = DB::table('user_balance_changes')
                  ->where($input)
                  ->orderBy('created_at','desc')
                  ->paginate($per_page)
                  ->toArray();
        $result['total_page'] = $result['last_page'];
        $arr = [];
        foreach($result['data'] as $re){
            $ar['resource_id']        = isset($re->resource_id)?$re->resource_id:'';
            $ar['resource_type']      = isset($re->resource_type)?$this->getResourceTypeStr($re->resource_type):'';
            $ar['thumbnail']          = asset('images/'.$re->resource_thumbnail);
            $ar['price']              = isset($re->price)?GeneralTool::priceFormat($re->price).'':'';
            $ar['created_at']         = isset($re->created_at)?$re->created_at:0;
            $ar['created_at_str']     = isset($re->created_at)?date('Y.m.d',$re->created_at):'';

            //3.1+版本字段
            $ar['time_group_str']     = date('Y年m月',$ar['created_at']);
            $ar['resource_type_str']  = isset($re->resource_type)?$this->getResourceTypeStr($re->resource_type,2):'';
            $ar['time_str']           = isset($re->created_at)?date('m-d H:i',$re->created_at):'';
            $arr[] = $ar;
        }
        $result['data'] = $arr;

        return $result;
    }

    //获取资源类别str
    function getResourceTypeStr($input, $type = 1){
        $str = $type == 2 ? '收入' : '';
        switch($input){
            case 'product':
                return '作品' . $str;
            case 'source':
                return '素材' . $str;
            default:
                return '';
        }
    }



    //提现记录
    function withdrawStatement($input){

        $result = DB::table('apply_withdraws')
                  ->where(['user_id'=>$input['user_id']])
                  ->orderBy('created_at','desc')
                  ->paginate($input['per_page'])
                  ->toArray();

        $result['total_page'] = $result['last_page'];
        $arr = [];

        foreach($result['data'] as $re){

            $ar['created_at']     = isset($re->created_at) ? $re->created_at : 0 ;
            $ar['created_at_str'] = $ar['created_at'] != 0 ? date('Y.m.d',$ar['created_at']) : '' ;
            $ar['price']          = isset($re->total_fee) ? GeneralTool::priceFormat($re->total_fee).'' : '' ;
            $ar['state_str']      = isset($re->state) ? $this->getWithdrawStateStr($re) : '' ;
            $ar['state']          = isset($re->state) ? $this->getWithdrawState($re) : '' ;
            $ar['withdraw_number']= isset($re->withdraw_number) ? $re->withdraw_number : '' ;

            //3.1版本字段
            $ar['time_group_str'] = date('Y年m月',$ar['created_at']);
            $ar['title']          = self::get_withdraw_title($re);
            $ar['time_str']       = isset($re->created_at)?date('m-d H:i',$re->created_at):'';
            //3.2
            $ar['poundage']       = isset($re->poundage) ? GeneralTool::priceFormat($re->poundage).'' : '' ;
            $arr[] = $ar;
        }

        $result['data'] = $arr;

        return $result;
    }

    //获取提现标题
    function get_withdraw_title($re){
        $str = (isset($re->bank_name) ? $re->bank_name : '') . '(' . (isset($re->bank_card_no) ? mb_substr($re->bank_card_no, -4) : '') . ')';
        return $str;
    }

    //获取提现单状态
    function getWithdrawStateStr($re){
        if($re->state==2){
            switch($re->result){
                case 1:
                    return '已到账';
                case 2:
                    return '失败';
                default:
                    return '';
            }
        }
        return '处理中';
    }

    //获取提现单状态
    function getWithdrawState($re){
        if($re->state==2){
            switch($re->result){
                case 1:
                    return 2;
                case 2:
                    return 3;
                default:
                    return 0;
            }
        }
        return 1;
    }

    //获取提现记录页用户数据
    function getUserBalanceWithdraw($input, $lists = 'total_fee'){
        $totals = SQL::lists(['table' => 'apply_withdraws',
                              'where' => $input,
                              'lists' => $lists]);
        return array_sum($totals).'';
    }

    //获取用户冻结金额
    function getUserBalanceFreeze($input){
        $totals   = $this->getUserBalanceWithdraw($input);
        $poundage = $this->getUserBalanceWithdraw($input,'poundage');
        return GeneralTool::priceFormat($totals + $poundage);
    }

    //提现记录
    function applyWithdraw($input){
        $input['withdraw_number'] = GeneralTool::only_no();
        $input['result_message']  = '';
        $input['created_at']      = time();
        $input['updated_at']      = $input['created_at'];
        $result = SQL::insert(['table'  => 'apply_withdraws',
                               'insert' => $input]);
        return $result;
    }

    //判断用户是否可提现
    function user_can_apply_withdraw($input){
        $cycle = SQL::pluck(['table' => 'configs',
                             'where' => ['name'  => 'apply_withddraw_cycle',
                                         'state' => 1],
                             'pluck' => 'value']);
        if(!isset($cycle) || !is_numeric($cycle)) return GeneralTool::createResult('','M00000');
        $cycle_times = SQL::pluck(['table' => 'configs',
                                   'where' => ['name'  => 'apply_withddraw_cycle_times',
                                               'state' => 1],
                                   'pluck' => 'value']);
        if(!isset($cycle_times) || !is_numeric($cycle_times) || $cycle_times < 0 ) return GeneralTool::createResult('','M00000');

        $arr  = self::get_apply_withdraw_cycle($cycle);
        $time = DB::table('apply_withdraws')
                ->where(['user_id' => $input])
                ->whereBetween('created_at',$arr)
                ->count();
        if($cycle_times <= $time)
            return ['state' => 'M00001', 'result' => (object)[], 'message' => '本月的提现次数已达上限'];
        else
            return ['state' => 'M00000', 'result' => (object)[], 'message' => '提现成功！本月可提现次数还剩' . ($cycle_times - $time) . '次'];
    }

    static function get_apply_withdraw_cycle($cycle){
        $now  = time();
        $mon  = date('m',$now);
        $year = date('Y',$now);
        $year_start = $year;
        $days = 0;
        $mon_start = $mon - $cycle + 1;
        if($mon_start <= 0){
            $mon_start += 12;
            $year_start--;
        }
        $begin = strtotime($year_start . '-' . $mon_start . '-1');
        $end   = strtotime($year . '-' . $mon . '-' . self::get_days($year,$mon) . ' 23:59:59');

        return [$begin, $end];
    }

    static function get_days($year,$mon){
        if($year%400 == 0  || ($year%4 == 0 && $year%100 !== 0)){
            $rday = 29;
        }else{
            $rday = 28;
        }
        if($mon==2){
            return $rday;
        }else{
            //判断是大月（31），还是小月（30）
            return (($mon - 1)%7%2) ? 30 : 31;
        }
    }

    //获取提现手续费
    static function get_poundage(){
        $result = SQL::pluck(['table' => 'configs',
                              'where' => ['name'  => 'withdraw_poundage',
                                          'state' => 1],
                              'pluck' => 'value']);
        if(!isset($result) || !is_numeric($result)) $result = 0 . '';
        return GeneralTool::priceFormat($result);
    }

    //获取提现最高金额
    static function get_withdraw_max(){
        $result = SQL::pluck(['table' => 'configs',
                              'where' => ['name'  => 'withdraw_max',
                                          'state' => 1],
                              'pluck' => 'value']);
        if(!isset($result) || !is_numeric($result)) $result = 0 . '';
        return GeneralTool::priceFormat($result);
    }

    /**
        Backstage
     */

    /**
        提现申请列表
     */
    function apply_withdraw_list_backstage($where, $input, $order = 'created_at', $sort = 'desc'){
        $lists = DB::table('apply_withdraws')
                 ->where($where)
                 ->orderBy($order,$sort)
                 ->paginate($input['per_page']);

        $lists->appends($input)->render();
        return $lists;
    }

    /**
        提现详情
     */
    function user_apply_withdraw_backstage($input){
        $result = SQL::first(['table' => 'apply_withdraws',
                              'where' => ['withdraw_id' => $input['withdraw_id']]]);
        return $result;
    }

    /**
        转账后操作
     */
    function transfer_accounts_after($input){
        $result = SQL::update(['table' => 'apply_withdraws',
                               'where' => ['withdraw_number' => $input['withdraw_number'],
                                           'state'           => 1,
                                           'is_over_withdraw'=> 0,
                                           'result'          => 0],
                               'update' => ['is_over_withdraw' => 1,
                                            'trade_no'         => $input['trade_no'],
                                            'updated_at'       => time()]]);
        return $result;
    }

    /**
        转账失败
     */
    function transfer_accounts_fail($input){
        $state = 'M00002';
        try{

            $result = SQL::update(['table' => 'apply_withdraws',
                                   'where' => ['withdraw_number' => $input['withdraw_number'],
                                               'state'           => 1,
                                               'is_over_withdraw'=> 0,
                                               'result'          => 0],
                                   'update' => ['is_over_withdraw' => 2,
                                                'result'           => 2,
                                                'state'            => 2,
                                                'result_message'   => (isset($input['result_message']) ? $input['result_message'] : ''),
                                                'updated_at'       => time()]]);
            if(!$result){
                $state = 'M00001';
                Throw new \Exception('转账失败->更新提现申请状态失败');
            }

            $re     = $this->changeBalance($input['user_id'], $input['total_fee'] + $input['poundage']);
            if(!$re){
                $state = 'M00001';
                Throw new \Exception('转账失败->更新用户余额失败');
            }
            return 'M00000';

        }catch(\Exception $e){
            Log::info($e);
            SQL::CatchDo();
            return $state;
        }finally{
            SQL::FinallyDo();
        }
    }

    /**
        回调成功
     */
    function transfer_accounts_notify($input){
        $result = SQL::update(['table' => 'apply_withdraws',
                               'where' => ['withdraw_number' => $input['withdraw_number'],
                                           'state'           => 1,
                                           'result'          => 0],
                               'update' => ['is_over_withdraw' => 2,
                                            'result'           => 1,
                                            'state'            => 2,
                                            'trade_no'         => $input['trade_no'],
                                            'updated_at'       => time()]]);
        return $result;
    }


    /**
        推送
     */

    /**
        提现申请推送
        参数：
            user_id         用户编号
            bank_name       银行名称
     */
    function submit_apply_withdraw_push($input){
        try{
            $title      = '提现申请成功';
            $message    = '你的提现申请已提交成功，预计三天内到账。提现银行：' . $input['bank_name'] . '    提现金额：' . $input['total_fee'];
            $message_in = '你的提现申请已提交成功，预计三天内到账。\n提现银行：' . $input['bank_name'] . '\n提现金额：' . $input['total_fee'];
            JpushTool::push($message,0,$input['user_id'],['title'      => $title,
                                                          'user_id'    => $input['user_id'],
                                                          'class'      => 'bill_notification',
                                                          'type'       => 1,
                                                          'jump_value' => '',
                                                          'template_no'=> '5',
                                                          'message'    => $message_in,
                                                          'images'     => []]);
        }catch(\Exception $e){

        }
    }

    /**
        提现成功推送
        参数:
            withdraw_number         提现单号
     */
    function apply_withdraw_success_push($input){
        $input['user_id'] = SQL::pluck(['table' => 'apply_withdraws',
                                        'where' => ['withdraw_number' => $input['withdraw_number']],
                                        'pluck' => 'user_id']);
        if(!isset($input['user_id'])) return ;
        try{
            $title      = '提现申请成功';
            $message    = '你有一单提现申请已处理完成，预计三日内到账，请注意查收~';
            $message_in = '你有一单提现申请已处理完成，预计三日内到账，请注意查收~';
            JpushTool::push($message,0,$input['user_id'],['title'      => $title,
                                                          'user_id'    => $input['user_id'],
                                                          'class'      => 'bill_notification',
                                                          'type'       => 1,
                                                          'jump_value' => '',
                                                          'template_no'=> '5',
                                                          'message'    => $message_in,
                                                          'images'     => []]);
        }catch(\Exception $e){

        }
    }

    /**
        接收订单分成
     */
    static function add_user_balance_change($obj, $input = []){
        /*
            user_balance_change
            user_balance
         */
        if(!isset($obj->user_id) || $obj->user_id == '' || $obj->user_id < 10001)
            return true;
        $arr['user_id']            = $obj->user_id;
        $arr['resource_id']        = $obj->resource_id;
        if($obj->type == 3)
            $arr['resource_type']  = 'source';
        else if($obj->type == 5)
            $arr['resource_type']  = 'product';

        $arr['resource_thumbnail'] = $obj->thumbnail;
        $arr['change_type']        = 1;
        $arr['price']              = $obj->preferential_price * $obj->quantity;
        $arr['type']               = 'income';
        $arr['ascription_type']    = isset($input['ascription_type']) ? $input['ascription_type'] : 'order';
        $arr['ascription_id']      = isset($obj->order_detail_fee_number) ? $obj->order_detail_fee_number : '';
        $arr['quantity']           = $obj->quantity;
        $arr['created_at']         = time();
        if($arr['price'] <= 0) return false;
        SQL::insert(['table' => 'user_balance_changes',
                     'insert'=> $arr]);
        $result = UserTool::changeBalance($obj->user_id, $arr['price']);
        $income = UserTool::addTotalRevenue($obj->user_id, $arr['price']);

        if($result && $income){
            self::add_user_balance_change_success_push($arr);
            return true;
        }
        return false;
    }

    /**
        进账推送
     */
    static function add_user_balance_change_success_push($input){
        if(isset($input['user_id']) && ($input['user_id'] == '' || intval($input['user_id']) == 0))
            return true;
        try{
            if(isset($input['resource_type']) && $input['resource_type'] == 'source')
                $input['type_str'] = '素材';
            else if(isset($input['resource_type']) && $input['resource_type'] == 'product')
                $input['type_str'] = '作品';
            else
                $input['type_str'] = '';

            $title      = '进账通知';
            $message    = '你有一笔收益已进账，可前往我的收益查看~';
            $message_in = '时间：' . date('Y-m-d H:i', $input['created_at']) .
                          '\n金额：' . GeneralTool::priceFormat($input['price']) .
                          '元\n类型：' . $input['type_str'] . '进账';
            JpushTool::push($message,0,$input['user_id'],['title'      => $title,
                                                          'user_id'    => $input['user_id'],
                                                          'class'      => 'bill_notification',
                                                          'type'       => 1,
                                                          'jump_value' => '',
                                                          'template_no'=> '4',
                                                          'message'    => $message_in,
                                                          'images'     => [['thumbnail'      => $input['resource_thumbnail'],
                                                                            'original_image' => $input['resource_thumbnail']]]]);
        }catch(\Exception $e){
            Log::info($e);
        }
    }

    /**
        修改用户余额
     */
    function changeBalance($user_id, $total_fee){
        return $this->userTool->changeBalance($user_id, $total_fee);
    }
}
